package com.springdata.dao;

import com.springdata.entity.Customer;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.support.JpaRepositoryImplementation;

import java.util.List;

/**
 * 符合Spring Data Jpa 的 Dao层接口规范
 * JpaRepository<操作的实体类型，实体类中主键属性的类型> 封装了基本CRUD操作
 * JpaSpecificationExecutor<操作的实体类型> 封装了复杂查询（分页）
 * JpaRepositoryImplementation<操作的实体类型，实体类中主键属性的类型> 继承了上面两个接口
 *
 * @author GLoRy
 * @date 2021/5/11 22:43
 */
public interface CustomerRepository extends JpaRepositoryImplementation<Customer, Long> {

    /**
     * 根据客户名称查询客户
     * JPQL:from Customer where customName = ?
     * 注意：在注解中 ? 后面要加index，意思是代表方法中的第几个参数，否则报错，低版本spring可以不加
     *
     * @param customName 客户名称
     * @return 客户信息
     */
    @Query(value = "from Customer where customName = ?1")
    Customer findByName(String customName);

    /**
     * 根据客户id和名称查询客户信息
     * JPQL:from Customer where id = ?1 and customName = ?2
     *
     * @param id   客户id
     * @param name 姓名
     * @return 客户信息
     */
    @Query(value = "from Customer where id = ?1 and customName = ?2")
    Customer findByIdAndName(Long id, String name);

    /**
     * 根据id更新客户名称
     * SQL：update t_customer set custom_name = ? where id = ?;
     * JPQL：update Customer set customName = ?2 where id = ?1
     *
     * @param name 客户名称
     * @param id   客户id
     * @Query ：用来进行查询操作，可以通过声明方法进行其他操作
     * @Modifying ：声明当前的方法是更新操作
     */
    @Query(value = "update Customer set customName = ?2 where id = ?1")
    @Modifying
    void updateCustomerNameById(Long id, String name);

    /**
     * 使用SQL查询全部的客户信息
     * value：SQL语句
     * nativeQuery ：true：使用本地查询SQL false：使用JPQL
     *
     * @return 全部客户信息
     */
    @Query(value = "select * from cst_customer", nativeQuery = true)
    List<Object[]> useSqlFindAll();

    /**
     * 使用SQL根据姓名模糊查询
     *
     * @param name 客户名称
     * @return 客户信息
     */
    @Query(value = "select * from cst_customer where custom_name like ?1", nativeQuery = true)
    List<Object[]> useSqlFindLikeName(String name);

    /**
     * 根据客户的姓名查询
     * findBy：查询
     * 查询的条件：对象中的属性名（首字母大写）
     * Spring Data JPA会解析：findBy(属性名称) from (实体类) where customName = ?
     * 默认方式：使用 "=" 的方式进行查询  findBy + 属性名称（根据属性名称完成匹配的查询）
     *
     * @param customName 客户名称
     * @return 客户信息
     */
    Customer findByCustomName(String customName);

    /**
     * 特殊的查询方式：findBy + 属性名称 + 查询方式（like | isnull 等等）
     * 模糊匹配查询
     *
     * @param customName 客户名称
     * @return 客户信息
     */
    List<Customer> findByCustomNameLike(String customName);

    /**
     * 多条件查询：findBy + 属性名称 + ”查询方式“ + 多条件的连接符（and | or）+ 属性名称 + ”查询方式“
     * 使用客户名称模糊匹配和来源精确匹配的查询
     *
     * @param customName   客户名称
     * @param customSource 客户来源
     * @return 客户
     */
    Customer findByCustomNameLikeAndCustomSource(String customName, String customSource);
}
